home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / 3Dfx / demos / tunnel.c < prev    next >
C/C++ Source or Header  |  1998-12-15  |  10KB  |  510 lines

  1. /*
  2.  * This program is under the GNU GPL.
  3.  * Use at your own risk.
  4.  *
  5.  * written by David Bucciarelli (tech.hmw@plus.it)
  6.  *            Humanware s.r.l.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <time.h>
  13.  
  14. #ifdef WIN32
  15. #include <windows.h>
  16. #endif
  17.  
  18. #include <GL/glut.h>
  19.  
  20. #include "image.h"
  21.  
  22. #ifdef XMESA
  23. #include "GL/xmesa.h"
  24. static int fullscreen=1;
  25. #endif
  26.  
  27. static int WIDTH=640;
  28. static int HEIGHT=480;
  29.  
  30. #define FRAME 50
  31.  
  32. #define NUMBLOC 5
  33.  
  34. #ifndef M_PI
  35. #define M_PI 3.1415926535
  36. #endif
  37.  
  38. extern int striplength_skin_13[];
  39. extern float stripdata_skin_13[];
  40.  
  41. extern int striplength_skin_12[];
  42. extern float stripdata_skin_12[];
  43.  
  44. extern int striplength_skin_11[];
  45. extern float stripdata_skin_11[];
  46.  
  47. extern int striplength_skin_9[];
  48. extern float stripdata_skin_9[];
  49.  
  50.  
  51. static int win=0;
  52.  
  53. static float obs[3]={1000.0,0.0,2.0};
  54. static float dir[3];
  55. static float v=0.0;
  56. static float alpha=90.0;
  57. static float beta=90.0;
  58.  
  59. static int fog=1;
  60. static int bfcull=1;
  61. static int usetex=1;
  62. static int cstrip=0;
  63. static int help=1;
  64. static int joyavailable=0;
  65. static int joyactive=0;
  66.  
  67. static int t1id,t2id;
  68.  
  69. static void inittextures(void)
  70. {
  71.   IMAGE *img;
  72.   GLenum gluerr;
  73.   
  74.   glGenTextures(1,&t1id);
  75.   glBindTexture(GL_TEXTURE_2D,t1id);
  76.  
  77.   if(!(img=ImageLoad("tile.rgb"))) {
  78.     fprintf(stderr,"Error reading a texture.\n");
  79.     exit(-1);
  80.   }
  81.  
  82.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  83.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  84.                    GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  85.     fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
  86.     exit(-1);
  87.   }
  88.  
  89.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  90.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  91.   
  92.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  93.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  94.  
  95.   glGenTextures(1,&t2id);
  96.   glBindTexture(GL_TEXTURE_2D,t2id);
  97.  
  98.   if(!(img=ImageLoad("bw.rgb"))) {
  99.     fprintf(stderr,"Error reading a texture.\n");
  100.     exit(-1);
  101.   }
  102.  
  103.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  104.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  105.                    GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  106.     fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
  107.     exit(-1);
  108.   }
  109.  
  110.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  111.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  112.   
  113.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  114.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  115.  
  116.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  117. }
  118.  
  119. static void drawobjs(int *l, float *f)
  120. {
  121.   int mend,j;
  122.  
  123.   if(cstrip) {
  124.     float r=0.33,g=0.33,b=0.33;
  125.  
  126.     for(;(*l)!=0;) {
  127.       mend=*l++;
  128.  
  129.       r+=0.33;
  130.       if(r>1.0) {
  131.     r=0.33;
  132.     g+=0.33;
  133.     if(g>1.0) {
  134.       g=0.33;
  135.       b+=0.33;
  136.       if(b>1.0)
  137.         b=0.33;
  138.     }
  139.       }
  140.  
  141.       glColor3f(r,g,b);
  142.       glBegin(GL_TRIANGLE_STRIP);
  143.       for(j=0;j<mend;j++) {
  144.     f+=4;
  145.     glTexCoord2fv(f); f+=2;
  146.     glVertex3fv(f); f+=3;
  147.       }
  148.       glEnd();
  149.     }
  150.   } else
  151.     for(;(*l)!=0;) {
  152.       mend=*l++;
  153.  
  154.       glBegin(GL_TRIANGLE_STRIP);
  155.       for(j=0;j<mend;j++) {
  156.     glColor4fv(f); f+=4;
  157.     glTexCoord2fv(f); f+=2;
  158.     glVertex3fv(f); f+=3;
  159.       }
  160.       glEnd();
  161.     }
  162. }
  163.  
  164. static float gettime(void)
  165. {
  166.   static clock_t told=0;
  167.   clock_t tnew,ris;
  168.  
  169.   tnew=clock();
  170.  
  171.   ris=tnew-told;
  172.  
  173.   told=tnew;
  174.  
  175.   return(ris/(float)CLOCKS_PER_SEC);
  176. }
  177.  
  178. static void calcposobs(void)
  179. {
  180.   dir[0]=sin(alpha*M_PI/180.0);
  181.   dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  182.   dir[2]=cos(beta*M_PI/180.0);
  183.  
  184.   obs[0]+=v*dir[0];
  185.   obs[1]+=v*dir[1];
  186.   obs[2]+=v*dir[2];
  187. }
  188.  
  189. static void special(int k, int x, int y)
  190. {
  191.   switch(k) {
  192.   case GLUT_KEY_LEFT:
  193.     alpha-=2.0;
  194.     break;
  195.   case GLUT_KEY_RIGHT:
  196.     alpha+=2.0;
  197.     break;
  198.   case GLUT_KEY_DOWN:
  199.     beta-=2.0;
  200.     break;
  201.   case GLUT_KEY_UP:
  202.     beta+=2.0;
  203.     break;
  204.   }
  205. }
  206.  
  207. static void key(unsigned char k, int x, int y)
  208. {
  209.   switch(k) {
  210.   case 27:
  211.     exit(0);
  212.     break;
  213.     
  214.   case 'a':
  215.     v+=0.01;
  216.     break;
  217.   case 'z':
  218.     v-=0.01;
  219.     break;
  220.  
  221. #ifdef XMESA
  222.   case ' ':
  223.     fullscreen=(!fullscreen);
  224.     XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  225.     break;
  226. #endif
  227.  
  228.   case 'j':
  229.     joyactive=(!joyactive);
  230.     break;
  231.   case 'h':
  232.     help=(!help);
  233.     break;
  234.   case 'f':
  235.     fog=(!fog);
  236.     break;
  237.   case 't':
  238.     usetex=(!usetex);
  239.     break;
  240.   case 'b':
  241.     if(bfcull) {
  242.       glDisable(GL_CULL_FACE);
  243.       bfcull=0;
  244.     } else {
  245.       glEnable(GL_CULL_FACE);
  246.       bfcull=1;
  247.     }
  248.     break;
  249.   case 'm':
  250.     cstrip=(!cstrip);
  251.     break;
  252.  
  253.   case 'd':
  254.     fprintf(stderr,"Deleting textures...\n");
  255.     glDeleteTextures(1,&t1id);
  256.     glDeleteTextures(1,&t2id);
  257.     fprintf(stderr,"Loading textures...\n");
  258.     inittextures();
  259.     fprintf(stderr,"Done.\n");
  260.     break;
  261.   }
  262. }
  263.  
  264. static void reshape(int w, int h) 
  265. {
  266.   WIDTH=w;
  267.   HEIGHT=h;
  268.   glMatrixMode(GL_PROJECTION);
  269.   glLoadIdentity();
  270.   gluPerspective(80.0,w/(float)h,1.0,50.0);
  271.   glMatrixMode(GL_MODELVIEW);
  272.   glLoadIdentity();
  273.   glViewport(0,0,w,h);
  274. }
  275.  
  276. static void printstring(void *font, char *string)
  277. {
  278.   int len,i;
  279.  
  280.   len=(int)strlen(string);
  281.   for(i=0;i<len;i++)
  282.     glutBitmapCharacter(font,string[i]);
  283. }
  284.  
  285. static void printhelp(void)
  286. {
  287.   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  288.   glColor4f(0.0,0.0,0.0,0.5);
  289.   glRecti(40,40,600,440);
  290.  
  291.   glColor3f(1.0,0.0,0.0);
  292.   glRasterPos2i(300,420);
  293.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");
  294.  
  295.   glRasterPos2i(60,390);
  296.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Togle Help");
  297.   glRasterPos2i(60,360);
  298.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Togle Textures");
  299.   glRasterPos2i(60,330);
  300.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Togle Fog");
  301.   glRasterPos2i(60,300);
  302.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"m - Togle strips");
  303.   glRasterPos2i(60,270);
  304.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Togle Back face culling");
  305.   glRasterPos2i(60,240);
  306.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  307.   glRasterPos2i(60,210);
  308.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  309.   glRasterPos2i(60,180);
  310.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  311.  
  312.   glRasterPos2i(60,150);
  313.   if(joyavailable)
  314.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Togle jostick control (Joystick control available)");
  315.   else
  316.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)");
  317. }
  318.  
  319. static void dojoy(void)
  320. {
  321. #ifdef WIN32
  322.   static UINT max[2]={0,0};
  323.   static UINT min[2]={0xffffffff,0xffffffff},center[2];
  324.   MMRESULT res;
  325.   JOYINFO joy;
  326.  
  327.   res=joyGetPos(JOYSTICKID1,&joy);
  328.  
  329.   if(res==JOYERR_NOERROR) {
  330.     joyavailable=1;
  331.  
  332.     if(max[0]<joy.wXpos)
  333.       max[0]=joy.wXpos;
  334.     if(min[0]>joy.wXpos)
  335.       min[0]=joy.wXpos;
  336.     center[0]=(max[0]+min[0])/2;
  337.  
  338.     if(max[1]<joy.wYpos)
  339.       max[1]=joy.wYpos;
  340.     if(min[1]>joy.wYpos)
  341.       min[1]=joy.wYpos;
  342.     center[1]=(max[1]+min[1])/2;
  343.  
  344.     if(joyactive) {
  345.       if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0]))
  346.     alpha-=2.0*(center[0]-(float)joy.wXpos)/(max[0]-min[0]);
  347.       if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1]))
  348.     beta+=2.0*(center[1]-(float)joy.wYpos)/(max[1]-min[1]);
  349.  
  350.       if(joy.wButtons & JOY_BUTTON1)
  351.     v+=0.01;
  352.       if(joy.wButtons & JOY_BUTTON2)
  353.     v-=0.01;
  354.     }
  355.   } else
  356.     joyavailable=0;
  357. #endif
  358. }
  359.  
  360. static void draw(void)
  361. {
  362.   static int count=0;
  363.   static char frbuf[80];
  364.   int i;
  365.   float fr,base,offset;
  366.  
  367.   dojoy();
  368.  
  369.   glClear(GL_COLOR_BUFFER_BIT);
  370.   
  371.   if(usetex)
  372.     glEnable(GL_TEXTURE_2D);
  373.   else
  374.     glDisable(GL_TEXTURE_2D);
  375.   
  376.   if(fog)
  377.     glEnable(GL_FOG);
  378.   else
  379.     glDisable(GL_FOG);
  380.   
  381.   glShadeModel(GL_SMOOTH);
  382.  
  383.   glPushMatrix();
  384.   calcposobs();
  385.   gluLookAt(obs[0],obs[1],obs[2],
  386.         obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
  387.         0.0,0.0,1.0);
  388.  
  389.   if(dir[0]>0) {
  390.     offset=8.0;
  391.     base=obs[0]-fmod(obs[0],8.0);
  392.   } else {
  393.     offset=-8.0;
  394.     base=obs[0]+(8.0-fmod(obs[0],8.0));
  395.   }
  396.  
  397.   glPushMatrix();
  398.   glTranslatef(base-offset/2.0,0.0,0.0);
  399.   for(i=0;i<NUMBLOC;i++) {
  400.     glTranslatef(offset,0.0,0.0);
  401.     glBindTexture(GL_TEXTURE_2D,t1id);
  402.     drawobjs(striplength_skin_11,stripdata_skin_11);
  403.     glBindTexture(GL_TEXTURE_2D,t2id);
  404.     drawobjs(striplength_skin_12,stripdata_skin_12);
  405.     drawobjs(striplength_skin_9,stripdata_skin_9);
  406.     drawobjs(striplength_skin_13,stripdata_skin_13);
  407.   }
  408.   glPopMatrix();
  409.   glPopMatrix();
  410.  
  411.   if((count % FRAME)==0) {
  412.     fr=gettime();
  413.     sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  414.   }
  415.  
  416.   glDisable(GL_TEXTURE_2D);
  417.   glDisable(GL_FOG);
  418.   glShadeModel(GL_FLAT);
  419.  
  420.   glMatrixMode(GL_PROJECTION);
  421.   glPushMatrix();
  422.   glLoadIdentity();
  423.   glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  424.  
  425.   glMatrixMode(GL_MODELVIEW);
  426.   glLoadIdentity();
  427.  
  428.   glColor3f(1.0,0.0,0.0);
  429.   glRasterPos2i(10,10);
  430.   printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  431.   glRasterPos2i(350,470);
  432.   printstring(GLUT_BITMAP_HELVETICA_10,"Tunnel V1.5 Written by David Bucciarelli (tech.hmw@plus.it)");
  433.  
  434.   if(help)
  435.     printhelp();
  436.  
  437.   glMatrixMode(GL_PROJECTION);
  438.   glPopMatrix();
  439.   glMatrixMode(GL_MODELVIEW);
  440.   
  441.   glutSwapBuffers();
  442.  
  443.   count++;
  444. }
  445.  
  446. int main(int ac, char **av)
  447. {
  448.   float fogcolor[4]={0.7,0.7,0.7,1.0};
  449.  
  450.   fprintf(stderr,"Tunnel V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  451.  
  452.   glutInitWindowPosition(0,0);
  453.   glutInitWindowSize(WIDTH,HEIGHT);
  454.   glutInit(&ac,av);
  455.  
  456.   glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_ALPHA);
  457.  
  458.   if(!(win=glutCreateWindow("Tunnel"))) {
  459.     fprintf(stderr,"Error, couldn't open window\n");
  460.     return -1;
  461.   }
  462.  
  463.   glMatrixMode(GL_PROJECTION);
  464.   glLoadIdentity();
  465.   gluPerspective(80.0,WIDTH/(float)HEIGHT,1.0,50.0);
  466.  
  467.   glMatrixMode(GL_MODELVIEW);
  468.  
  469.   glShadeModel(GL_SMOOTH);
  470.   glDisable(GL_DEPTH_TEST);
  471.   glEnable(GL_CULL_FACE);
  472.   glEnable(GL_TEXTURE_2D);
  473.  
  474.   glEnable(GL_FOG);
  475.   glFogi(GL_FOG_MODE,GL_EXP2);
  476.   glFogfv(GL_FOG_COLOR,fogcolor);
  477.  
  478.   glFogf(GL_FOG_DENSITY,0.06);
  479.  
  480. #ifdef FX
  481.   glHint(GL_FOG_HINT,GL_NICEST);
  482. #endif
  483.  
  484.   inittextures();
  485.  
  486. #ifndef FX
  487.   glDisable(GL_TEXTURE_2D);
  488.   usetex=0;
  489. #endif
  490.  
  491.   glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]);
  492.   glClear(GL_COLOR_BUFFER_BIT);
  493.  
  494.   calcposobs();
  495.  
  496.   glutReshapeFunc(reshape);
  497.   glutDisplayFunc(draw);
  498.   glutKeyboardFunc(key);
  499.   glutSpecialFunc(special);
  500.   glutIdleFunc(draw);
  501.  
  502.   glEnable(GL_BLEND);
  503.   glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE);
  504.   glEnable(GL_POLYGON_SMOOTH);
  505.  
  506.   glutMainLoop();
  507.  
  508.   return 0;
  509. }
  510.